package com.huabo.base;

import com.huabo.sql.separation.DataSourceChange;
import org.apache.log4j.Logger;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;

@Transactional
public class BaseServiceImpl<T extends BaseModel, PK extends Serializable, Dao extends BaseDao<T, PK>> implements BaseService<T, PK>, ApplicationContextAware {

	protected static final Logger log = Logger.getLogger(BaseServiceImpl.class);

	private Dao dao;
	protected ApplicationContext context;

	protected Dao getDao() {
		if (dao != null) {
			return dao;
		}
		init();
		return dao;
	}
	
	@SuppressWarnings("unchecked")
	@PostConstruct
	public void init() {
		Type type = this.getClass().getGenericSuperclass();
		if(type instanceof ParameterizedType) {
			Class<Dao> daoClass = (Class<Dao>) ((ParameterizedType)type).getActualTypeArguments()[2];
			dao = context.getBean(daoClass);
		} else {
			throw new RuntimeException("SubClass must give the ActualTypeArguments");
		}
	}

	@DataSourceChange(slave = false)
	@Override
	public int save(T t) {
		return dao.insert(t);
	}

	@DataSourceChange(slave = false)
	@Override
	public int batchSave(List<T> list) {
		return dao.batchInsert(list);
	}

	@DataSourceChange(slave = false)
	@Override
	public int modify(T t) {
		return dao.update(t);
	}

	@DataSourceChange(slave = false)
	@Override
	public int modifyForce(T t) {
		return dao.updateForce(t);
	}

	@DataSourceChange(slave = false)
	@Override
	public int remove(PK id) {
		return dao.delete(id);
	}

	@Override
	public int remove(PK[] ids) {
		return dao.delete(ids);
	}

	/*@DataSourceChange(slave = true)
	@Override
	public List<T> queryList(QueryCondition qc) {
		return dao.query(qc);
	}*/

	/*@DataSourceChange(slave = true)
	@Override
	public Page<T> queryPage(QueryCondition qc) {
		return dao.queryPage(qc);
	}*/

	/*@DataSourceChange(slave = true)
	@Override
	public int count(QueryCondition qc) {
		return dao.count(qc);
	}*/

	@DataSourceChange(slave = true)
	@Override
	public T load(PK id) {
		return dao.load(id);
	}

	/*@DataSourceChange(slave = false)
	@Override
	public int deleteByCondition(QueryCondition qc) {
		return dao.deleteByCondition(qc);
	}*/

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		this.context = applicationContext;
	}
}
